home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 February / EnigmA AMIGA RUN 04 (1996)(G.R. Edizioni)(IT)[!][issue 1996-02][Skylink CD III].iso / earcd / comm2 / kms20src.lha / KMSC / init.c < prev    next >
C/C++ Source or Header  |  1995-09-24  |  16KB  |  654 lines

  1. /**********************************
  2.  *              KMS               *
  3.  **********************************
  4.  *  ©1992 by BlackMagic Software  *
  5.  **********************************
  6.  *                                *
  7.  **********************************/
  8.  
  9. #include <KMS/KMS.h>
  10. #include <KMS/KMS_devlib.h>
  11. #include <KMS/KMS_intui.h>
  12.  
  13. /* A handy macro to access AbsExecBase. */
  14.  
  15. #define SysBase (*(struct ExecBase **)4L)
  16.  
  17. Prototype UBYTE OpenLib(VOID);
  18. Prototype UBYTE Identify(VOID);
  19. Prototype UBYTE OpenTimer(VOID);
  20. Prototype UBYTE OpenDisplay(VOID);
  21. Prototype VOID Sense(UBYTE);
  22. Prototype VOID TakeMSem(BOOL);
  23. Prototype VOID DropMSem(VOID);
  24.  
  25. LONG IsInteractive(BPTR);
  26.  
  27. /*****************************
  28.  * Externe Globale Variablen *
  29.  *****************************/
  30.  
  31. extern struct IntuitionBase *IntuitionBase;
  32. extern struct GfxBase *GfxBase;
  33.  
  34. extern STRPTR CmdArgV[];
  35. extern STRPTR MsgHead[];
  36. extern STRPTR MsgInfos[];
  37.  
  38. extern UMSAccount MyUMSAccount;
  39.  
  40. extern struct rexxCommandList RCL[];
  41. extern struct rexxCommandList TempRCL[];
  42.  
  43. extern STRPTR KMSTitle;
  44.  
  45. /*********************
  46.  * Globale Variablen *
  47.  *********************/
  48.  
  49. struct Library *DiskfontBase = NULL;
  50. struct MsgPort *Timer_Port = NULL;
  51. struct timerequest *Time_Request = NULL;
  52. struct DosPacket *InputPacket = NULL;
  53.  
  54. ULONG TimerSignal, RexxSignal, InputSignal;
  55.  
  56. TEXT KMSWinTitle[81];
  57.  
  58. /* Konfiguration */
  59.  
  60. struct KMSBase *KMSBase = NULL;
  61. struct LocalConfig *KMS_LC = NULL;
  62.  
  63. /* System-UMS-Account */
  64.  
  65. UMSUserAccount SysUMSAccount = 0;
  66.  
  67. /* Name unseres privaten MsgPort */
  68.  
  69. TEXT RexxPortName[16];
  70. STRPTR RexxExtension = "KMS";
  71.  
  72. /* Temp-Dateiname */
  73.  
  74. TEXT KMSTempDat[LEN_NUMBER+11] = "";
  75.  
  76. /* Alter Systemrequester-Windowzeiger (weil umgebogen) */
  77.  
  78. static APTR OldWindowPtr = NULL;
  79.  
  80. /* InOut-Fenster-Dimensionen */
  81.  
  82. BOOL OwnScreen;
  83.  
  84. /* StdErr Filehandle */
  85.  
  86. BPTR StdErr = NULL;
  87.  
  88. /* PC-Font */
  89.  
  90. BOOL UsePCFont = FALSE;
  91. struct TextFont *PCTextFont = NULL;
  92. struct TextAttr PCFont =
  93.    {
  94.    "IBM.font",
  95.    8,
  96.    FS_NORMAL,
  97.    FPF_DISKFONT
  98.    };
  99.  
  100. /* Dummy-User */
  101.  
  102. struct UserNode DummyUser;
  103.  
  104. /*******************************************
  105.  * Öffnen der Libraries u.a.               *
  106.  *******************************************
  107.  * I: ---                                  *
  108.  * O: Fehlercode                           *
  109.  *******************************************/
  110.  
  111. /// "OpenLib"
  112.  
  113. UBYTE OpenLib(VOID)
  114.    {
  115.    StdErr = (BPTR)Open("CON:0/10//100/KMSPort Error/CLOSE/AUTO/WAIT", MODE_OLDFILE);
  116.  
  117.    if (SysBase->LibNode.lib_Version < 37)
  118.       {
  119.       Error("FATAL ERROR: [OpenLib] AmigaOS >=2.04 needed");
  120.       return 1;
  121.       }
  122.    DiskfontBase = (struct Library *)OpenLibrary("diskfont.library", 33);
  123.    if (!DiskfontBase)
  124.       {
  125.       Error("FATAL ERROR: [OpenLib] couldn't OpenLibrary(diskfont.library)");
  126.       return 2;
  127.       }
  128.    if (!(KMS_LC = AllocMem((ULONG)sizeof(struct LocalConfig), MEMF_PUBLIC|MEMF_CLEAR)))
  129.       {
  130.       Error("FATAL ERROR: [OpenLib] couldn't AllocMem(KMS_LC)");
  131.       return 4;
  132.       }
  133.  
  134.    /* Command-History-Liste initialisieren */
  135.  
  136.    NewList((struct List *)&KMS_LC->HistoryList);
  137.  
  138.    /* LocalConfig initialisieren */
  139.  
  140.    KMS_LC->Device = DEV_CONSOLE;
  141.    KMS_LC->HistCount = 0;
  142.    KMS_LC->Cursor = TRUE;
  143.  
  144.    /* Kommando-Parameterliste initialisieren */
  145.  
  146.    UBYTE n;
  147.    for(n = 0; n < MAXCMDARGS; n++)
  148.       CmdArgV[n] = NULL;
  149.  
  150.    return 0;
  151.    }
  152.  
  153. ///
  154.  
  155. /***************************************
  156.  * Client beim Master anmelden         *
  157.  ***************************************
  158.  * I: ---                              *
  159.  * O: 0: Ok >0: Fehler                 *
  160.  ***************************************/
  161.  
  162. /// "Identify"
  163.  
  164. UBYTE Identify(VOID)
  165.    {
  166.    struct KMSNode *newentry;
  167.    UWORD res = 0;
  168.    UBYTE count = 0;
  169.  
  170.    /* System-Login */
  171.  
  172.    TEXT varbuff[32] = "";
  173.    TEXT pwbuff[32] = "";
  174.    GetVar("KMSMB", varbuff, sizeof(varbuff), NULL);
  175.    GetVar("KMSPWD", pwbuff, sizeof(pwbuff), NULL);
  176.    if (!(SysUMSAccount = UMSRLogin(varbuff, "KMS", pwbuff)))
  177.       {
  178.       Error("FATAL ERROR: [Identify] couldn't log into UMS");
  179.       return 1;
  180.       }
  181.  
  182.    /* Eventuell Server starten */
  183.  
  184.    if (!FindPort("KMSServer"))
  185.       {
  186.       TEXT dosbuff[LEN_DOSPATH+1];
  187.       STRPTR bindir;
  188.  
  189.       if (bindir = ReadUMSConfigTags(SysUMSAccount, UMSTAG_CfgName, "KMS.BinDir", TAG_DONE))
  190.          {
  191.          strcpy(dosbuff, bindir);
  192.          if (strlen(dosbuff))
  193.             if (dosbuff[strlen(dosbuff)-1] != ':' && dosbuff[strlen(dosbuff)-1] != '/')
  194.                strcat(dosbuff, "/");
  195.  
  196.          FreeUMSConfig(SysUMSAccount, bindir);
  197.          }
  198.       else
  199.          *dosbuff = '\0';
  200.  
  201.       strcat(dosbuff, "KMSServer >NIL: <NIL:");
  202.  
  203.       SystemTags(dosbuff, SYS_Input, NULL, SYS_Output, NULL, SYS_Asynch, TRUE, TAG_DONE);
  204.       }
  205.  
  206.    /* Warten auf Server-Rexx-Port */
  207.  
  208.    count = 0;
  209.    while(!FindPort("KMS") && count++ < 15)
  210.       Delay(50);
  211.    if (!FindPort("KMS"))
  212.       {
  213.       Error("FATAL ERROR: [Identify] Port KMS not found");
  214.       return 1;
  215.       }
  216.  
  217.    /* KMSBase besorgen und anmelden */
  218.  
  219.    if (!(KMSBase = (struct KMSBase *)FindSemaphore(KMSBASENAME)))
  220.       {
  221.       Error("FATAL ERROR: [Identify] KMSBase not found");
  222.       return 1;
  223.       }
  224.    else
  225.       ObtainSemaphoreShared(&KMSBase->BaseSem);
  226.  
  227.    /* System ID ermitteln */
  228.  
  229.    TakeMSem(TRUE);
  230.  
  231.    UWORD previd = 0, id = 0;
  232.    struct KMSNode *mpoint = KMSBase->MemberList.mlh_Head;
  233.    if (mpoint->Node.mln_Succ)
  234.       id = mpoint->LCPtr->ID;
  235.  
  236.    while(mpoint->Node.mln_Succ && previd == id - 1)
  237.       {
  238.       previd = id;
  239.       mpoint = mpoint->Node.mln_Succ;
  240.       if (mpoint->Node.mln_Succ)
  241.          id = mpoint->LCPtr->ID;
  242.       }
  243.  
  244.    KMS_LC->ID = previd + 1;
  245.  
  246.    /* neuen MemberList-Eintrag erzeugen */
  247.  
  248.    if (!(newentry = AllocMem((ULONG)sizeof(struct KMSNode), MEMF_PUBLIC|MEMF_CLEAR)))
  249.       {
  250.       Error("FATAL ERROR: [Identify] couldn't AllocMem(KMSNode)");
  251.       return 1;
  252.       }
  253.  
  254.    newentry->LCPtr = KMS_LC;
  255.    AddTail((struct List *)&KMSBase->MemberList, (struct Node *)newentry);
  256.  
  257.    DropMSem();
  258.  
  259.    /* Rexx-Port-Namen erzeugen */
  260.  
  261.    sprintf(RexxPortName, "KMS.%d", KMS_LC->ID);
  262.  
  263.    /* Rexx-Port einrichten */
  264.  
  265.    if (!(RexxSignal = upRexxPort(RexxPortName, RCL, RexxExtension, &KMSRexxDisp)))
  266.       {
  267.       Error("FATAL ERROR: [Identify] couldn't upRexxPort(RexxPortName)");
  268.       return 1;
  269.       }
  270.  
  271.    sprintf(KMSTempDat, "T:KMS_%d.TMP", KMS_LC->ID);
  272.  
  273.    return 0;
  274.    }
  275.  
  276. ///
  277.  
  278. /***************************************
  279.  * Öffnen des timer.device             *
  280.  ***************************************
  281.  * I: ---                              *
  282.  * O: struct timerequest *Time_Request *
  283.  ***************************************/
  284.  
  285. /// "OpenTimer"
  286.  
  287. UBYTE OpenTimer(VOID)
  288.    {
  289.    if (!(Timer_Port = (struct MsgPort *)CreatePort(NULL, 0)))
  290.       {
  291.       Error("FATAL ERROR: [OpenTimer] couldn't CreatePort(Timer_Port)");
  292.       return 1;
  293.       }
  294.    if (!(Time_Request = (struct timerequest *)CreateExtIO(Timer_Port, (ULONG)sizeof(struct timerequest))))
  295.       {
  296.       Error("FATAL ERROR: [OpenTimer] couldn't CreateExtIO(Time_Request)");
  297.       return 2;
  298.       }
  299.    if (OpenDevice(TIMERNAME, UNIT_VBLANK, (struct IORequest *)Time_Request, NULL))
  300.       {
  301.       Error("FATAL ERROR: [OpenTimer] couldn't OpenDevice(timer.device)");
  302.       return 3;
  303.       }
  304.  
  305.    TimerSignal = (1L << Time_Request->tr_node.io_Message.mn_ReplyPort->mp_SigBit);
  306.  
  307.    return 0;
  308.    }
  309.  
  310. ///
  311.  
  312. /*********************************
  313.  * Öffnen von Screen und Fenster *
  314.  *********************************
  315.  * I: ---                        *
  316.  * O: Fehlercode                 *
  317.  *********************************/
  318.  
  319. /// "OpenDisplay"
  320.  
  321. UBYTE OpenDisplay(VOID)
  322.    {
  323.    struct Screen *myscreen;
  324.    struct Window *mywindow;
  325.  
  326.    sprintf(KMSWinTitle, "%s Port %d", KMSTitle, KMS_LC->ID);
  327.  
  328.    if (!strlen(KMS_LC->WinDim))
  329.       {
  330.       /* STDIO-Port */
  331.  
  332.       KMS_LC->InHandle = Input();
  333.       KMS_LC->OutHandle = Output();
  334.  
  335.       if (!KMS_LC->InHandle || !KMS_LC->OutHandle)
  336.          {
  337.          Error("FATAL ERROR: [OpenDisplay] IO-Failure");
  338.          return 1;
  339.          }
  340.       }
  341.    else
  342.       {
  343.       /* WINDOW angegeben */
  344.  
  345.       if (OwnScreen)
  346.          {
  347.          /* KMS-Screen öffnen, wenn nicht schon vorhanden */
  348.  
  349.          myscreen = LockPubScreen(KMSPNAME);
  350.          if (!myscreen)
  351.             {
  352.             /* Screen öffnen */
  353.  
  354.             struct Screen *wbscreen = LockPubScreen(NULL);
  355.             if (!wbscreen)
  356.                {
  357.                Error("FATAL ERROR: [OpenDisplay] couldn't lock default public screen");
  358.                return 2;
  359.                }
  360.             struct DrawInfo *wbdrawinfo = GetScreenDrawInfo(wbscreen);
  361.             if (!wbdrawinfo)
  362.                {
  363.                UnlockPubScreen(NULL, wbscreen);
  364.  
  365.                Error("FATAL ERROR: [OpenDisplay] couldn't GetScreenDrawInfo()");
  366.                return 2;
  367.                }
  368.             ULONG wbmodeid = GetVPModeID(&(wbscreen->ViewPort));
  369.             if (wbmodeid == INVALID_ID)
  370.                {
  371.                FreeScreenDrawInfo(wbscreen, wbdrawinfo);
  372.                UnlockPubScreen(NULL, wbscreen);
  373.  
  374.                Error("FATAL ERROR: [OpenDisplay] couldn't GetVPModeID()");
  375.                return 2;
  376.                }
  377.  
  378.             myscreen = (struct Screen *)
  379.                        OpenScreenTags(NULL, SA_Title, (ULONG)KMSTitle,
  380.                                             SA_Type, PUBLICSCREEN,
  381.                                             SA_Overscan, OSCAN_TEXT,
  382.                                             SA_DisplayID, wbmodeid,
  383.                                             SA_AutoScroll, TRUE,
  384.                                             SA_PubName, (ULONG)KMSPNAME,
  385.                                             SA_SysFont, 1,
  386.                                             SA_Width, wbscreen->Width,
  387.                                             SA_Height, wbscreen->Height,
  388.                                             SA_Depth, wbdrawinfo->dri_Depth,
  389.                                             SA_Pens, (ULONG)(wbdrawinfo->dri_Pens),
  390.                                             TAG_DONE);
  391.  
  392.             FreeScreenDrawInfo(wbscreen, wbdrawinfo);
  393.             UnlockPubScreen(NULL, wbscreen);
  394.  
  395.             if (!myscreen)
  396.                {
  397.                Error("FATAL ERROR: [OpenDisplay] couldn't OpenScreenTags(myscreen)");
  398.                return 3;
  399.                }
  400.  
  401.             if (!(PubScreenStatus(myscreen, 0) & 1))
  402.                {
  403.                Error("FATAL ERROR: [OpenDisplay] Screen couldn't be made public");
  404.                return 4;
  405.                }
  406.             }
  407.          else
  408.             UnlockPubScreen(NULL, myscreen);
  409.          }
  410.  
  411.       /* Fenster gemäß WINDOW-Angabe öffnen */
  412.  
  413.       KMS_LC->InHandle = Open(KMS_LC->WinDim, MODE_OLDFILE);
  414.       KMS_LC->OutHandle = KMS_LC->InHandle;
  415.  
  416.       if (!KMS_LC->InHandle || !KMS_LC->OutHandle)
  417.          {
  418.          Error("FATAL ERROR: [OpenDisplay] IO-Failure");
  419.          return 1;
  420.          }
  421.       
  422.       if (KMS_LC->Device & DEV_CONSOLE)
  423.          {
  424.          if (mywindow = GetWindow())
  425.             {
  426.             SetWindowTitles(mywindow, (STRPTR)-1L, KMSWinTitle);
  427.  
  428.             if (UsePCFont)
  429.                {
  430.                struct TextFont *old_tf;
  431.                PCTextFont = (struct TextFont *)OpenDiskFont(&PCFont);
  432.                if (PCTextFont)
  433.                   {
  434.                   old_tf = mywindow->RPort->Font;
  435.                   if (SetFont(mywindow->RPort, PCTextFont))
  436.                      {
  437.                      CloseFont(old_tf);
  438.                      Print("\33c", PF_NOLF|PF_NOBRK);
  439.                      }
  440.                   else
  441.                      {
  442.                      CloseFont(PCTextFont);
  443.                      PCTextFont = NULL;
  444.                      }
  445.                   }
  446.                }
  447.             }
  448.          }
  449.       }
  450.  
  451.    /* DosPacket für Input-Handling */
  452.  
  453.    InputPacket = AllocDosObject(DOS_STDPKT, NULL);
  454.    if (!InputPacket)
  455.       {
  456.       Error("FATAL ERROR: [OpenDisplay] AllocDosObject");
  457.       return 5;
  458.       }
  459.  
  460.    struct MsgPort *inport = CreatePort(NULL, 0);
  461.    if (!inport)
  462.       {
  463.       Error("FATAL ERROR: [OpenDisplay] CreatePort");
  464.       return 5;
  465.       }
  466.  
  467.    InputPacket->dp_Link->mn_ReplyPort = inport;
  468.    InputPacket->dp_Type = ACTION_WAIT_CHAR;
  469.  
  470.    InputSignal = 1L << inport->mp_SigBit;
  471.  
  472.    /* In RAW:-Modus schalten */
  473.  
  474.    if (IsInteractive(KMS_LC->InHandle))
  475.       SetMode(KMS_LC->InHandle, 1);
  476.    KMS_LC->RawMode = TRUE;
  477.  
  478.    /* Systemrequester-Windowzeiger umbiegen */
  479.  
  480.    struct Process *myprocess = (struct Process *)FindTask(NULL);
  481.    OldWindowPtr = myprocess->pr_WindowPtr;
  482.    myprocess->pr_WindowPtr = (APTR)-1L;
  483.  
  484.    return 0;
  485.    }
  486.  
  487. ///
  488.  
  489. /*********************************************
  490.  * Schließen aller Libraries, Fenster usw... *
  491.  *********************************************
  492.  *** I: Exit-Code                            *
  493.  *** O: ---                                  *
  494.  *********************************************/
  495.  
  496. /// "Sense"
  497.  
  498. VOID Sense(UBYTE exitcode)
  499.    {
  500.    /* Systemrequester-Windowzeiger wieder zurücksetzen */
  501.  
  502.    if (OldWindowPtr)
  503.       {
  504.       struct Process *myprocess = (struct Process *)FindTask(NULL);
  505.       myprocess->pr_WindowPtr = OldWindowPtr;
  506.       }
  507.  
  508.    /* Rexx-Port killen */
  509.  
  510.    dnRexxPort();
  511.  
  512.    /* Diverse Aufräumarbeiten */
  513.  
  514.    if (KMS_LC)
  515.       {
  516.       /* Command-History-Liste freigeben */
  517.  
  518.       struct HistoryNode *hpoint = KMS_LC->HistoryList.mlh_Head;
  519.       while(hpoint->Node.mln_Succ)
  520.          {
  521.          struct HistoryNode *nexthpoint = hpoint->Node.mln_Succ;
  522.          Remove((struct Node *)hpoint);
  523.          FreeMem(hpoint, (ULONG)sizeof(struct HistoryNode));
  524.          hpoint = nexthpoint;
  525.          }
  526.       }
  527.  
  528.    if (KMSBase && KMS_LC)
  529.       {
  530.       /* IO-Kanäle/Fenster schließen, falls WINDOW-Angabe vorhanden war */
  531.  
  532.       if (strlen(KMS_LC->WinDim))
  533.          {
  534.          if (KMS_LC->InHandle)
  535.             Close(KMS_LC->InHandle);
  536.          }
  537.       else
  538.          {
  539.          /* In CON: Modus schalten */
  540.  
  541.          if (KMS_LC->InHandle && IsInteractive(KMS_LC->InHandle))
  542.             SetMode(KMS_LC->InHandle, 0);
  543.          }
  544.  
  545.       if (KMS_LC->SpyHandle)
  546.          Close(KMS_LC->SpyHandle);
  547.  
  548.       /* Evt. Screen schließen */
  549.  
  550.       if (KMSBase->MemberList.mlh_Head == KMSBase->MemberList.mlh_TailPred)
  551.          {
  552.          struct Screen *myscreen;
  553.  
  554.          if (myscreen = LockPubScreen(KMSPNAME))
  555.             {
  556.             UnlockPubScreen(NULL, myscreen);
  557.  
  558.             Delay(50);
  559.             while(!CloseScreen(myscreen))
  560.                Delay(50);
  561.             }
  562.          }
  563.  
  564.       /* Aus der MemberList ausklinken */
  565.  
  566.       TakeMSem(TRUE);
  567.  
  568.       struct KMSNode *mpoint = KMSBase->MemberList.mlh_Head;
  569.       if (mpoint->Node.mln_Succ)
  570.          {
  571.          while(mpoint->Node.mln_Succ && mpoint->LCPtr != KMS_LC)
  572.             mpoint = mpoint->Node.mln_Succ;
  573.  
  574.          if (mpoint->Node.mln_Succ && mpoint->LCPtr == KMS_LC)
  575.             {
  576.             Remove((struct Node *)mpoint);
  577.             FreeMem(mpoint, (ULONG)sizeof(struct KMSNode));
  578.             }
  579.          }
  580.  
  581.       DropMSem();
  582.       }
  583.  
  584.    /* Von KMSBase abmelden */
  585.  
  586.    if (KMSBase)
  587.       ReleaseSemaphore(&KMSBase->BaseSem);
  588.  
  589.    /* Diverse Aufräumarbeiten */
  590.  
  591.    if (InputPacket)
  592.       {
  593.       DeletePort(InputPacket->dp_Link->mn_ReplyPort);
  594.       FreeDosObject(DOS_STDPKT, InputPacket);
  595.       }
  596.    if (Time_Request && Time_Request->tr_node.io_Device)
  597.       CloseDevice((struct IORequest *)Time_Request);
  598.    if (Time_Request)
  599.       DeleteExtIO((struct IORequest *)Time_Request);
  600.    if (Timer_Port)
  601.       DeletePort(Timer_Port);
  602.  
  603.    if (KMS_LC)
  604.       FreeMem(KMS_LC, (ULONG)sizeof(struct LocalConfig));
  605.  
  606.    UBYTE n;
  607.    for(n = 0; n < MAXCMDARGS; n++)
  608.       {
  609.       if (CmdArgV[n])
  610.          free(CmdArgV[n]);
  611.       }
  612.  
  613.    if (strlen(KMSTempDat))
  614.       DeleteFile(KMSTempDat);
  615.  
  616.    if (MyUMSAccount)
  617.       UMSLogout(MyUMSAccount);
  618.    if (SysUMSAccount)
  619.       UMSLogout(SysUMSAccount);
  620.  
  621.    if (PCTextFont)
  622.       CloseFont(PCTextFont);
  623.    if (DiskfontBase)
  624.       CloseLibrary(DiskfontBase);
  625.  
  626.    if (StdErr)
  627.       Close(StdErr);
  628.  
  629.    exit(exitcode);
  630.    }
  631.  
  632. ///
  633.  
  634. /// "TakeMSem"
  635.  
  636. VOID TakeMSem(BOOL exclusive)
  637.    {
  638.    if (exclusive)
  639.       ObtainSemaphore(&KMSBase->SaveSem);
  640.    else
  641.       ObtainSemaphoreShared(&KMSBase->SaveSem);
  642.    }
  643.  
  644. ///
  645.  
  646. /// "DropMSem"
  647.  
  648. VOID DropMSem(VOID)
  649.    {
  650.    ReleaseSemaphore(&KMSBase->SaveSem);
  651.    }
  652.  
  653. ///
  654.